package com.kelp.codetoolkit.actions

import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.LangDataKeys
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.Messages
import com.intellij.psi.PsiJavaFile
import com.kelp.codetoolkit.enums.RemoteInvocationFrameworkEnum
import com.kelp.codetoolkit.enums.ServerPackageEnum
import com.kelp.codetoolkit.respository.CodeToolkitGlobalSettingRepository
import com.kelp.codetoolkit.service.MethodHandleService
import com.kelp.codetoolkit.ui.form.MethodParamsSettingDialog


/**
 * @author: liuyuebai
 * @date: 2024/10/17 14:39
 * @description:
 */
class MethodGeneratorAction:AnAction() {
    override fun actionPerformed(e: AnActionEvent) {
        val project = e.project?:return
        val psiFile = e.getData(LangDataKeys.PSI_FILE)?: return
        val virtualFile = psiFile.virtualFile
        if ("xml".equals(virtualFile.extension, ignoreCase = true)) {
            Messages.showErrorDialog(project, "Currently, the selected file does not support synchronous method generation.", "Error");
        }
        if (psiFile is PsiJavaFile){
            val className = psiFile.classes[0].name?:return
            val serverPackageEnum = ServerPackageEnum.getServerPackageEnumByClassName(className)
            if (null == serverPackageEnum) {
                Messages.showErrorDialog(project, "Currently, the selected file does not support synchronous method generation.", "Error")
                return
            }

            val dialog = MethodParamsSettingDialog(project)
            if (dialog.showAndGet()) {
                handleFileWriteMethod(project,psiFile,serverPackageEnum,dialog)
            }
        }
    }

    private fun handleFileWriteMethod(project: Project, psiJavaFile: PsiJavaFile, serverPackageEnum: ServerPackageEnum, methodContent:MethodParamsSettingDialog){
        val methodName = methodContent.getMethodName()
        if (methodName.isBlank()){
            Messages.showErrorDialog(project,"Method name must mot empty","ERROR")
            return
        }
        val currentClassName = psiJavaFile.classes[0].name?:return
        val settingState = CodeToolkitGlobalSettingRepository.getInstance(project).state
        val methodHandleService = MethodHandleService.getInstance(project)
        if(ServerPackageEnum.isService(currentClassName)){
            val entityClassName =  currentClassName.replace(ServerPackageEnum.SERVICE.suffix,"")
            methodHandleService.handleService(project, psiJavaFile,methodContent)
            methodHandleService.handleJavaMapper(project,methodContent, psiJavaFile,entityClassName,serverPackageEnum)
            methodHandleService.handleServiceImpl(project,methodContent, psiJavaFile,entityClassName,serverPackageEnum)
            if (RemoteInvocationFrameworkEnum.OPENFEIGN.value == settingState.getRemoteInvocationFramework()){
                methodHandleService.handleController(project,methodContent, psiJavaFile,entityClassName,serverPackageEnum)
            }
            if (RemoteInvocationFrameworkEnum.DUBBO.value == settingState.getRemoteInvocationFramework()){
                methodHandleService.handleProviderImpl(project,methodContent, psiJavaFile,entityClassName,serverPackageEnum)
                methodHandleService.handleProvider(project,methodContent, psiJavaFile,entityClassName,serverPackageEnum)
            }
            methodHandleService.handleMapperXml(project,psiJavaFile,methodContent,entityClassName)
        }
        if(ServerPackageEnum.isJavaMapper(currentClassName)){
            val entityClassName =  currentClassName.replace(ServerPackageEnum.MAPPER_JAVA.suffix,"")
            methodHandleService.handleJavaMapper(project, psiJavaFile,methodContent)
            methodHandleService.handleService(project,methodContent, psiJavaFile,entityClassName,serverPackageEnum)
            methodHandleService.handleServiceImpl(project,methodContent, psiJavaFile,entityClassName,serverPackageEnum)
            if (RemoteInvocationFrameworkEnum.OPENFEIGN.value == settingState.getRemoteInvocationFramework()){
                methodHandleService.handleController(project,methodContent, psiJavaFile,entityClassName,serverPackageEnum)
            }
            if (RemoteInvocationFrameworkEnum.DUBBO.value == settingState.getRemoteInvocationFramework()){
                methodHandleService.handleProviderImpl(project,methodContent, psiJavaFile,entityClassName,serverPackageEnum)
                methodHandleService.handleProvider(project,methodContent, psiJavaFile,entityClassName,serverPackageEnum)
            }
            methodHandleService.handleMapperXml(project,psiJavaFile,methodContent,entityClassName)
        }

        if(ServerPackageEnum.isServiceImpl(currentClassName)){
            val entityClassName =  currentClassName.replace(ServerPackageEnum.SERVICE_IMPL.suffix,"")
            methodHandleService.handleServiceImpl(project, psiJavaFile,methodContent)
            methodHandleService.handleService(project,methodContent, psiJavaFile,entityClassName,serverPackageEnum)
            methodHandleService.handleJavaMapper(project,methodContent, psiJavaFile,entityClassName,serverPackageEnum)
            if (RemoteInvocationFrameworkEnum.OPENFEIGN.value == settingState.getRemoteInvocationFramework()){
                methodHandleService.handleController(project,methodContent, psiJavaFile,entityClassName,serverPackageEnum)
            }
            if (RemoteInvocationFrameworkEnum.DUBBO.value == settingState.getRemoteInvocationFramework()){
                methodHandleService.handleProviderImpl(project,methodContent, psiJavaFile,entityClassName,serverPackageEnum)
                methodHandleService.handleProvider(project,methodContent, psiJavaFile,entityClassName,serverPackageEnum)
            }
            methodHandleService.handleMapperXml(project,psiJavaFile,methodContent,entityClassName)
        }

        if(ServerPackageEnum.isProviderImpl(currentClassName)){
            val entityClassName =  currentClassName.replace(ServerPackageEnum.PROVIDER_IMPL.suffix,"")
            methodHandleService.handleProviderImpl(project, psiJavaFile,methodContent)
            methodHandleService.handleService(project,methodContent, psiJavaFile,entityClassName,serverPackageEnum)
            methodHandleService.handleServiceImpl(project,methodContent, psiJavaFile,entityClassName,serverPackageEnum)
            methodHandleService.handleJavaMapper(project,methodContent, psiJavaFile,entityClassName,serverPackageEnum)
            methodHandleService.handleProvider(project,methodContent, psiJavaFile,entityClassName,serverPackageEnum)
            methodHandleService.handleMapperXml(project,psiJavaFile,methodContent,entityClassName)
        }
//
        if(ServerPackageEnum.isProvider(currentClassName)){
            val entityClassName =  currentClassName.replace(ServerPackageEnum.PROVIDER.suffix,"")
            methodHandleService.handleProvider(project, psiJavaFile,methodContent)
            methodHandleService.handleProviderToProviderImpl(project,methodContent, psiJavaFile,entityClassName,serverPackageEnum)
            methodHandleService.handleProviderToService(project,methodContent, psiJavaFile,entityClassName,serverPackageEnum)
            methodHandleService.handleProviderToServiceImpl(project,methodContent, psiJavaFile,entityClassName,serverPackageEnum)
            methodHandleService.handleProviderToJavaMapper(project,methodContent, psiJavaFile,entityClassName,serverPackageEnum)
            methodHandleService.handleProviderToMapperXml(project,psiJavaFile,methodContent,entityClassName)
        }

        if(ServerPackageEnum.isController(currentClassName)){
            val entityClassName =  currentClassName.replace(ServerPackageEnum.CONTROLLER.suffix,"")
            methodHandleService.handleController(project, psiJavaFile,methodContent)
            methodHandleService.handleService(project,methodContent, psiJavaFile,entityClassName,serverPackageEnum)
            methodHandleService.handleServiceImpl(project,methodContent, psiJavaFile,entityClassName,serverPackageEnum)
            methodHandleService.handleJavaMapper(project,methodContent, psiJavaFile,entityClassName,serverPackageEnum)
            methodHandleService.handleMapperXml(project,psiJavaFile,methodContent,entityClassName)
        }
    }

}